package site.wlwsjsx.iot_backend.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import site.wlwsjsx.iot_backend.entity.*;
import site.wlwsjsx.iot_backend.service.exception.ServiceException;
import site.wlwsjsx.iot_backend.mapper.*;
import site.wlwsjsx.iot_backend.service.ReceiveService;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;

@Service
public class ReceiveServiceImpl implements ReceiveService {
    private static final Logger logger = LoggerFactory.getLogger(ReceiveServiceImpl.class);

    @Resource
    private EmergencyPowerOffEventMapper emergencyPowerOffEventMapper;

    @Resource
    private WorkstationInfoMapper workstationInfoMapper;

    @Resource
    private WorkstationEnvMapper workstationEnvMapper;

    @Resource
    private LabInfoMapper labInfoMapper;

    @Resource
    private LabEnvMapper labEnvMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private AlertEventMapper alertEventMapper;

    @Resource
    private DeviceEventMapper deviceEventMapper;

    private static LocalDateTime lastPropertyUpdateTime;
    private static LocalDateTime lastEventUpdateTime;

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    /**
     * 处理从JSON格式接收的消息
     * @param msg 接收到的JSON格式消息字符串
     * @throws ServiceException 当JSON解析或消息处理过程中出现错误时抛出
     */
    public void dealMessageFromJson(String msg) throws ServiceException {
        try {
            // 使用ObjectMapper将JSON字符串转换为JsonNode对象
            JsonNode rootNode = objectMapper.readTree(msg);
            // 记录接收到的原始消息
            logger.info("接收到消息: {}", rootNode.toString());

            // 根据notifyType字段分类处理消息
            if (rootNode.has("notifyType")) {
                // 获取notifyType字段的值
                String notifyType = rootNode.get("notifyType").asText();
                // 记录正在处理的notifyType类型
                logger.info("处理notifyType为: {} 的消息", notifyType);

                // 根据不同的notifyType值进行相应处理
                switch (notifyType) {
                    case "property":
                        // 处理属性数据消息（正常的环境数据）
                        handlePropertyMessage(rootNode);
                        break;
                    case "event":
                        // 处理事件消息（告警、故障等）
                        handleEventMessage(rootNode);
                        break;
                    default:
                        // 处理未知的notifyType类型
                        logger.warn("未知的notifyType: {}", notifyType);
                        handleUnknownNotifyTypeMessage(rootNode, notifyType);
                }
            } else {
                // 处理没有notifyType字段的消息（设备上下线通知等）
                logger.info("处理无notifyType字段的消息（设备上下线通知）");
                handleDeviceOnlineOfflineMessage(rootNode);
            }

        } catch (JsonProcessingException e) {
            // 记录JSON解析错误
            logger.error("JSON解析错误", e);
            // 抛出带有错误信息的ServiceException
            throw new ServiceException("JSON解析失败: " + e.getMessage(), e);
        } catch (Exception e) {
            // 记录处理消息时发生的其他错误
            logger.error("处理消息时发生错误", e);
            // 抛出带有错误信息的ServiceException
            throw new ServiceException("处理消息时发生错误: " + e.getMessage(), e);
        }
    }

    /**
     * 处理属性消息的方法
     * 支持物模型设备属性消息格式
     *
     * @param rootNode 包含设备信息的JSON节点
     * @throws ServiceException 处理属性消息时发生错误
     */
    private void handlePropertyMessage(JsonNode rootNode) throws ServiceException {
        try {
            // 创建工作站环境对象
            WorkstationEnv workstationEnv = new WorkstationEnv();

            // 从JSON节点中获取基本信息
            String productId = rootNode.get("productId").asText();
            String deviceName = rootNode.get("deviceName").asText();
            String messageType = rootNode.get("messageType").asText();
            String notifyType = rootNode.get("notifyType").asText();

            logger.info("处理物模型属性消息 - 产品ID: {}, 设备名称: {}, 消息类型: {}, 通知类型: {}",
                    productId, deviceName, messageType, notifyType);

            // 设置工作站代码
            workstationEnv.setWorkstationCode(deviceName);

            // 解析数据部分
            JsonNode dataNode = rootNode.get("data");
            if (dataNode == null) {
                throw new ServiceException("属性消息中缺少data字段");
            }

            // 获取参数节点
            JsonNode paramsNode = dataNode.get("params");
            if (paramsNode == null) {
                throw new ServiceException("属性消息中缺少params字段");
            }

            logger.info("开始解析物模型属性数据，设备: {}, 参数数量: {}", deviceName, paramsNode.size());

            // 解析属性数据
            parsePropertyData(paramsNode, workstationEnv);

            // 记录解析结果
            logger.info("属性数据解析完成 - " + workstationEnv.toString());

            LocalDateTime currentTime = LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
            if (lastPropertyUpdateTime == null || !lastPropertyUpdateTime.isEqual(currentTime)) {
                lastPropertyUpdateTime = currentTime;
                // 保存数据到数据库
                if (workstationEnv.getCurUsername() != null && !workstationEnv.getCurUsername().equals("null")) {
                    // 处理工位环境数据
                    UserInfo userInfo = userMapper.selectUserByUsername(workstationEnv.getCurUsername());
                    System.out.println(userInfo.toString());
                    WorkstationInfo workstationInfo = workstationInfoMapper.selectByCode(workstationEnv.getWorkstationCode());
                    workstationInfo.setPowerStatus(workstationEnv.getPowerStatus());
                    workstationInfo.setLightStatus(workstationEnv.getLightStatus());
                    workstationInfo.setRelayNum1Status(workstationEnv.getRelayNum1Status());
                    workstationInfo.setRelayNum2Status(workstationEnv.getRelayNum2Status());
                    workstationInfo.setCurUserId(userInfo.getId());
                    workstationInfoMapper.updateById(workstationInfo.getId(), workstationInfo);
                    logger.info("工作站信息更新成功 - {}", workstationInfo.toString());
                    // 保存数据到数据库
                    if (workstationEnvMapper.insert(workstationEnv) <= 0) {
                        throw new ServiceException("保存工作站环境数据失败");
                    }
                    logger.info("工作站环境数据保存成功 - 设备: {}", deviceName);
                } else {
                    // 处理工位环境数据
                    WorkstationInfo workstationInfo = workstationInfoMapper.selectByCode(workstationEnv.getWorkstationCode());
                    workstationInfo.setPowerStatus(workstationEnv.getPowerStatus());
                    workstationInfo.setLightStatus(workstationEnv.getLightStatus());
                    workstationInfo.setRelayNum1Status(workstationEnv.getRelayNum1Status());
                    workstationInfo.setRelayNum2Status(workstationEnv.getRelayNum2Status());
                    workstationInfo.setCurUserId(null);
                    workstationInfoMapper.updateById(workstationInfo.getId(), workstationInfo);
                    logger.info("工作站信息更新成功 - {}", workstationInfo.toString());
                }
                // 处理实验室环境数据
                handleLabEnvData(productId, workstationEnv);
                logger.info("保存实验室环境数据");
            } else {
                logger.info("重复数据不做保存");
            }
        } catch (Exception e) {
            logger.error("处理property消息时发生错误", e);
            throw new ServiceException("处理property消息时发生错误: " + e.getMessage(), e);
        }
    }

    /**
     * 处理事件消息的方法
     * 支持两种事件消息格式：
     * 1. 告警事件格式（AlertEmergency等）
     * 2. 物模型设备事件格式（identifier1、identifier2等）
     *
     * @param rootNode 包含事件信息的JSON节点
     * @throws ServiceException 处理事件消息时发生错误
     */
    private void handleEventMessage(JsonNode rootNode) throws ServiceException {
        try {
            // 解析基本信息
            String productId = rootNode.get("productId").asText();
            String deviceName = rootNode.get("deviceName").asText();
            String messageType = rootNode.get("messageType").asText();
            String notifyType = rootNode.get("notifyType").asText();

            logger.info("处理事件消息 - 产品ID: {}, 设备名称: {}, 消息类型: {}, 通知类型: {}",
                    productId, deviceName, messageType, notifyType);

            // 获取包含事件数据的JSON子节点
            JsonNode dataNode = rootNode.get("data");
            if (dataNode == null) {
                throw new ServiceException("事件消息中缺少data字段");
            }

            // 解析事件参数
            JsonNode paramsNode = dataNode.get("params");
            if (paramsNode == null) {
                throw new ServiceException("事件消息中缺少params字段");
            }

            logger.info("开始处理事件参数，设备: {}, 参数数量: {}", deviceName, paramsNode.size());

            LocalDateTime currentTime = LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
            ;

            // 添加去重逻辑
            if (lastEventUpdateTime == null || !lastEventUpdateTime.isEqual(currentTime)) {
                lastEventUpdateTime = currentTime;

                // 遍历所有事件参数，处理不同类型的事件
                paramsNode.fieldNames().forEachRemaining(identifier -> {
                    try {
                        JsonNode eventData = paramsNode.get(identifier);
                        handleEventIdentifier(deviceName, identifier, eventData);
                    } catch (Exception e) {
                        logger.error("处理事件标识符 {} 时发生错误", identifier, e);
                    }
                });
            } else {
                logger.info("重复事件数据不做处理 - 设备: {}, 时间: {}", deviceName, currentTime);
            }

        } catch (Exception e) {
            logger.error("处理event消息时发生错误", e);
            throw new ServiceException("处理event消息时发生错误: " + e.getMessage(), e);
        }
    }


    /**
     * 处理事件标识符
     * 支持两种事件数据格式：
     * 1. 告警事件格式（AlertEmergency等）
     * 2. 物模型设备事件格式（identifier1、identifier2等）
     *
     * @param deviceName 设备名称
     * @param identifier 事件标识符（如AlertEmergency、identifier1等）
     * @param eventData  事件数据
     */
    private void handleEventIdentifier(String deviceName, String identifier, JsonNode eventData) {
        try {
            logger.info("处理事件标识符 - 设备: {}, 标识符: {}", deviceName, identifier);

            // 解析事件时间戳
            long timestamp = eventData.get("time").asLong();
            LocalDateTime eventTime = convertTimestamp(timestamp);

            // 解析事件值
            JsonNode valueNode = eventData.get("value");
            if (valueNode == null) {
                logger.warn("事件数据中缺少value字段 - 设备: {}, 标识符: {}", deviceName, identifier);
                return;
            }

            // 判断事件类型并分别处理
            if (isAlertEvent(identifier)) {
                // 处理告警事件（如AlertEmergency）
                handleAlertEvent(deviceName, identifier, valueNode, eventTime);
            } else {
                // 处理物模型设备事件（如identifier1、identifier2）
                handleDeviceEvent(deviceName, identifier, valueNode, eventTime);
            }

        } catch (Exception e) {
            logger.error("处理事件标识符时发生错误 - 设备: {}, 标识符: {}", deviceName, identifier, e);
        }
    }

    /**
     * 判断是否为告警事件
     * 基于物模型定义中的事件类型进行判断
     *
     * @param identifier 事件标识符
     * @return true表示是告警事件，false表示是设备事件
     */
    private boolean isAlertEvent(String identifier) {
        // 基于物模型定义的事件类型进行判断
        return identifier.equals("AlertEmergency") || // 紧急告警事件
                identifier.equals("AlertWarning") || // 警告事件
                identifier.equals("EmergencyPowerOff") || // 紧急断电事件
                identifier.startsWith("Alert") || // 其他Alert开头的事件
                identifier.contains("Emergency") || // 包含Emergency的事件
                identifier.contains("Fault") || // 包含Fault的事件
                identifier.contains("Warning"); // 包含Warning的事件
    }

    /**
     * 处理告警事件
     * 基于物模型定义处理AlertEmergency、AlertWarning、EmergencyPowerOff等告警事件
     *
     * @param deviceName 设备名称
     * @param identifier 事件标识符
     * @param valueNode  事件值节点
     * @param eventTime  事件时间
     */
    private void handleAlertEvent(String deviceName, String identifier, JsonNode valueNode, LocalDateTime eventTime) {
        try {
            logger.warn("处理告警事件 - 设备: {}, 事件类型: {}, 时间: {}", deviceName, identifier, eventTime);

            // 根据物模型定义的事件类型分别处理
            switch (identifier) {
                case "AlertEmergency":
                    handleAlertEmergencyEvent(deviceName, valueNode, eventTime);
                    break;
                case "AlertWarning":
                    handleAlertWarningEvent(deviceName, valueNode, eventTime);
                    break;
                case "EmergencyPowerOff":
                    handleEmergencyPowerOffEvent(deviceName, valueNode, eventTime);
                    break;
                default:
                    handleGenericAlertEvent(deviceName, identifier, valueNode, eventTime);
                    break;
            }

        } catch (Exception e) {
            logger.error("处理告警事件时发生错误 - 设备: {}, 事件: {}", deviceName, identifier, e);
        }
    }

    /**
     * 处理AlertEmergency紧急告警事件
     * 基于物模型定义：包含alertType, severity, sensorValue, threshold, timestamp, userId,
     * temperature, humidity, flameScope, smokeScope
     */
    private void handleAlertEmergencyEvent(String deviceName, JsonNode valueNode, LocalDateTime eventTime) {
        try {
            String alertType = valueNode.has("alertType") ? valueNode.get("alertType").asText() : "UNKNOWN";
            String severity = valueNode.has("severity") ? valueNode.get("severity").asText() : "UNKNOWN";
            double sensorValue = valueNode.has("sensorValue") ? valueNode.get("sensorValue").asDouble() : 0.0;
            double threshold = valueNode.has("threshold") ? valueNode.get("threshold").asDouble() : 0.0;
            String username = valueNode.has("username") ? valueNode.get("username").asText() : "unknown";
            double temperature = valueNode.has("temperature") ? valueNode.get("temperature").asDouble() : 0.0;
            double humidity = valueNode.has("humidity") ? valueNode.get("humidity").asDouble() : 0.0;
            double flameScope = valueNode.has("flameScope") ? valueNode.get("flameScope").asDouble() : 0.0;
            double smokeScope = valueNode.has("smokeScope") ? valueNode.get("smokeScope").asDouble() : 0.0;

            logger.error("紧急告警事件 - 设备: {}, 告警类型: {}, 严重程度: {}, 传感器值: {}, " +
                            "阈值: {}, 用户名: {}, 温度: {}, 湿度: {}, 火焰值: {}, 烟雾值: {}",
                    deviceName, alertType, severity, sensorValue, threshold, username,
                    temperature, humidity, flameScope, smokeScope);

            // 保存紧急告警事件到数据库
            AlertEvent alertEvent = new AlertEvent();
            alertEvent.setDeviceId(deviceName);
            alertEvent.setAlertType(alertType);
            alertEvent.setSeverity(severity);
            alertEvent.setSensorValue((float) sensorValue);
            alertEvent.setThreshold((float) threshold);
            alertEvent.setUsername(username); // 存储username
            alertEvent.setTemperature((float) temperature);
            alertEvent.setHumidity((float) humidity);
            alertEvent.setFlameScope((float) flameScope);
            alertEvent.setSmokeScope((float) smokeScope);
            alertEvent.setCreateTime(eventTime);
            alertEvent.setProcessed(0);

            try {
                alertEventMapper.insert(alertEvent);
                logger.info("紧急告警事件已保存到数据库 - ID: {}", alertEvent.getId());
            } catch (Exception e) {
                logger.error("保存紧急告警事件到数据库失败", e);
            }
        } catch (Exception e) {
            logger.error("处理AlertEmergency事件时发生错误 - 设备: {}", deviceName, e);
        }
    }

    /**
     * 处理AlertWarning警告事件
     * 基于物模型定义：包含alertType, severity, sensorValue, threshold, timestamp, userId,
     * temperature, humidity, flameScope, smokeScope
     */
    private void handleAlertWarningEvent(String deviceName, JsonNode valueNode, LocalDateTime eventTime) {
        try {
            String alertType = valueNode.has("alertType") ? valueNode.get("alertType").asText() : "UNKNOWN";
            String severity = valueNode.has("severity") ? valueNode.get("severity").asText() : "UNKNOWN";
            double sensorValue = valueNode.has("sensorValue") ? valueNode.get("sensorValue").asDouble() : 0.0;
            double threshold = valueNode.has("threshold") ? valueNode.get("threshold").asDouble() : 0.0;
            String username = valueNode.has("username") ? valueNode.get("username").asText() : "unknown";
            double temperature = valueNode.has("temperature") ? valueNode.get("temperature").asDouble() : 0.0;
            double humidity = valueNode.has("humidity") ? valueNode.get("humidity").asDouble() : 0.0;
            double flameScope = valueNode.has("flameScope") ? valueNode.get("flameScope").asDouble() : 0.0;
            double smokeScope = valueNode.has("smokeScope") ? valueNode.get("smokeScope").asDouble() : 0.0;

            logger.warn("警告事件 - 设备: {}, 告警类型: {}, 严重程度: {}, 传感器值: {}, " +
                            "阈值: {}, 用户名: {}, 温度: {}, 湿度: {}, 火焰值: {}, 烟雾值: {}",
                    deviceName, alertType, severity, sensorValue, threshold, username,
                    temperature, humidity, flameScope, smokeScope);

            // 保存警告事件到数据库
            AlertEvent alertEvent = new AlertEvent();
            alertEvent.setDeviceId(deviceName);
            alertEvent.setAlertType(alertType);
            alertEvent.setSeverity(severity);
            alertEvent.setSensorValue((float) sensorValue);
            alertEvent.setThreshold((float) threshold);
            alertEvent.setUsername(username);
            alertEvent.setTemperature((float) temperature);
            alertEvent.setHumidity((float) humidity);
            alertEvent.setFlameScope((float) flameScope);
            alertEvent.setSmokeScope((float) smokeScope);
            alertEvent.setCreateTime(eventTime);
            alertEvent.setProcessed(0);

            try {
                alertEventMapper.insert(alertEvent);
                logger.info("警告事件已保存到数据库 - ID: {}", alertEvent.getId());
            } catch (Exception e) {
                logger.error("保存警告事件到数据库失败", e);
            }
        } catch (Exception e) {
            logger.error("处理AlertWarning事件时发生错误 - 设备: {}", deviceName, e);
        }
    }

    /**
     * 处理EmergencyPowerOff紧急断电事件
     * 基于物模型定义：包含reason, timestamp
     */
    private void handleEmergencyPowerOffEvent(String deviceName, JsonNode valueNode, LocalDateTime eventTime) {
        try {
            String username = valueNode.has("username") ? valueNode.get("username").asText() : "0000000001";
            String reason = valueNode.has("reason") ? valueNode.get("reason").asText() : "UNKNOWN";

            logger.error("🔌 紧急断电事件 - 设备: {}, 当前用户: {}, 原因: {}, 时间: {}", deviceName, username, reason, eventTime);

            // 保存紧急断电事件到数据库
            EmergencyPowerOffEvent emergencyPowerOffEvent = new EmergencyPowerOffEvent();
            emergencyPowerOffEvent.setDeviceId(deviceName);
            emergencyPowerOffEvent.setReason(reason);
            emergencyPowerOffEvent.setUsername(username);
            emergencyPowerOffEvent.setProcessed(0); // 0表示未处理

            try {
                emergencyPowerOffEventMapper.insert(emergencyPowerOffEvent);
                logger.info("紧急断电事件已保存到数据库 - ID: {}", emergencyPowerOffEvent.getId());
            } catch (Exception e) {
                logger.error("保存紧急断电事件到数据库失败", e);
            }
        } catch (Exception e) {
            logger.error("处理EmergencyPowerOff事件时发生错误 - 设备: {}", deviceName, e);
        }
    }

    /**
     * 处理通用告警事件
     * 处理其他未明确定义的告警事件
     */
    private void handleGenericAlertEvent(String deviceName, String identifier, JsonNode valueNode,
                                         LocalDateTime eventTime) {
        try {
            logger.warn("⚠️ 通用告警事件 - 设备: {}, 事件类型: {}, 时间: {}, 数据: {}",
                    deviceName, identifier, eventTime, valueNode.toString());
        } catch (Exception e) {
            logger.error("处理通用告警事件时发生错误 - 设备: {}, 事件: {}", deviceName, identifier, e);
        }
    }

    /**
     * 处理物模型设备事件
     * 处理identifier1、identifier2等设备事件
     *
     * @param deviceName 设备名称
     * @param identifier 事件标识符
     * @param valueNode  事件值节点
     * @param eventTime  事件时间
     */
    private void handleDeviceEvent(String deviceName, String identifier, JsonNode valueNode, LocalDateTime eventTime) {
        try {
            logger.info("处理设备事件 - 设备: {}, 标识符: {}, 时间: {}", deviceName, identifier, eventTime);

            // 创建工作站环境对象来存储事件数据
            WorkstationEnv envInfo = new WorkstationEnv();
            envInfo.setWorkstationCode(deviceName);
            envInfo.setCreateTime(eventTime);

            // 解析设备事件中的属性数据
            valueNode.fieldNames().forEachRemaining(fieldName -> {
                try {
                    JsonNode fieldValue = valueNode.get(fieldName);
                    parseEventPropertyField(fieldName, fieldValue, envInfo);
                } catch (Exception e) {
                    logger.warn("解析设备事件属性字段 {} 时发生错误: {}", fieldName, e.getMessage());
                }
            });

            // 记录解析结果
            logger.info("设备事件数据解析完成 - 设备: {}, 标识符: {}, 温度: {}, 电源状态: {}",
                    deviceName, identifier, envInfo.getTemperature(), envInfo.getPowerStatus());

            // 保存设备事件到数据库
            DeviceEvent deviceEvent = new DeviceEvent();
            deviceEvent.setDeviceId(deviceName);
            deviceEvent.setEventIdentifier(identifier);
            deviceEvent.setEventType("device_event");
            deviceEvent.setEventData(valueNode.toString());
            deviceEvent.setTemperature(envInfo.getTemperature());
            deviceEvent.setHumidity(envInfo.getHumidity());
            deviceEvent.setPowerStatus(envInfo.getPowerStatus());
            deviceEvent.setLightStatus(envInfo.getLightStatus());
            deviceEvent.setRelayNum1Status(envInfo.getRelayNum1Status());
            deviceEvent.setRelayNum2Status(envInfo.getRelayNum2Status());
            deviceEvent.setLightIntensity(envInfo.getLightIntensity());
            deviceEvent.setSmokeScope(envInfo.getSmokeScope());
            deviceEvent.setFlameScope(envInfo.getFlameScope());
            deviceEvent.setHeatScope(envInfo.getHeatScope());
            deviceEvent.setUserId(envInfo.getCurUsername());
            deviceEvent.setEventTime(eventTime);
            deviceEvent.setCreateTime(LocalDateTime.now());
            deviceEvent.setProcessed(false);

            try {
                deviceEventMapper.insert(deviceEvent);
                logger.info("设备事件已保存到数据库 - ID: {}", deviceEvent.getId());
            } catch (Exception e) {
                logger.error("保存设备事件到数据库失败", e);
            }
        } catch (Exception e) {
            logger.error("处理设备事件时发生错误 - 设备: {}, 标识符: {}", deviceName, identifier, e);
        }
    }

    /**
     * 解析设备事件中的属性字段
     * 专门用于解析事件消息中的属性数据
     *
     * @param fieldName  字段名
     * @param fieldValue 字段值
     * @param envInfo    工作站环境信息对象
     */
    private void parseEventPropertyField(String fieldName, JsonNode fieldValue, WorkstationEnv envInfo) {
        switch (fieldName) {
            // 温度相关字段
            case "WF":
            case "Temperature":
            case "CurrentTemperature":
                if (fieldValue.isNumber()) {
                    envInfo.setTemperature((float) fieldValue.asDouble());
                    logger.debug("解析事件温度数据: {}", fieldValue.asDouble());
                } else if (fieldValue.isTextual()) {
                    try {
                        envInfo.setTemperature(Float.parseFloat(fieldValue.asText()));
                        logger.debug("解析事件温度数据: {}", fieldValue.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析温度数据: {}", fieldValue.asText());
                    }
                }
                break;

            // 电源状态相关字段
            case "Power":
            case "PowerStatus":
                if (fieldValue.isTextual()) {
                    String powerValue = fieldValue.asText().toLowerCase();
                    envInfo.setPowerStatus("on".equals(powerValue) ? 1 : 0);
                    logger.debug("解析事件电源状态: {} -> {}", powerValue, envInfo.getPowerStatus());
                } else if (fieldValue.isNumber()) {
                    envInfo.setPowerStatus(fieldValue.asInt());
                    logger.debug("解析事件电源状态: {}", fieldValue.asInt());
                }
                break;

            // 湿度相关字段
            case "Humidity":
            case "RelativeHumidity":
                if (fieldValue.isNumber()) {
                    envInfo.setHumidity((float) fieldValue.asDouble());
                    logger.debug("解析事件湿度数据: {}", fieldValue.asDouble());
                } else if (fieldValue.isTextual()) {
                    try {
                        envInfo.setHumidity(Float.parseFloat(fieldValue.asText()));
                        logger.debug("解析事件湿度数据: {}", fieldValue.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析湿度数据: {}", fieldValue.asText());
                    }
                }
                break;

            // 其他传感器数据字段
            case "SmokeScope":
            case "Smoke":
                if (fieldValue.isNumber()) {
                    envInfo.setSmokeScope((float) fieldValue.asDouble());
                    logger.debug("解析事件烟雾数据: {}", fieldValue.asDouble());
                }
                break;

            case "FlameScope":
            case "Flame":
                if (fieldValue.isNumber()) {
                    envInfo.setFlameScope((float) fieldValue.asDouble());
                    logger.debug("解析事件火焰数据: {}", fieldValue.asDouble());
                }
                break;

            case "LightIntensity":
            case "Light":
                if (fieldValue.isNumber()) {
                    envInfo.setLightIntensity((float) fieldValue.asDouble());
                    logger.debug("解析事件光照强度: {}", fieldValue.asDouble());
                }
                break;

            case "HeatScope":
            case "Heat":
                if (fieldValue.isNumber()) {
                    envInfo.setHeatScope((float) fieldValue.asDouble());
                    logger.debug("解析事件热敏传感器数据: {}", fieldValue.asDouble());
                }
                break;

            // 用户名字段 - 物模型定义: Username (string) 对应UserInfo.username
            case "Username":
                if (fieldValue.isTextual()) {
                    String username = fieldValue.asText();
                    envInfo.setCurUsername(username);
                    logger.debug("解析设备事件用户名: {}", username);
                }
                break;

            default:
                logger.debug("未识别的设备事件属性字段: {} = {}", fieldName, fieldValue.toString());
                break;
        }
    }

    /**
     * 处理设备上下线通知消息
     * 处理没有notifyType字段的设备状态变化消息
     *
     * @param rootNode 包含设备状态信息的JSON节点
     * @throws ServiceException 处理设备上下线消息时发生错误
     */
    private void handleDeviceOnlineOfflineMessage(JsonNode rootNode) throws ServiceException {
        try {
            logger.info("处理设备上下线通知消息");
            // TODO: 实现设备上下线通知处理逻辑
            logger.info("设备上下线通知处理完成 - 消息内容: {}", rootNode.toString());

        } catch (Exception e) {
            logger.error("处理设备上下线通知消息时发生错误", e);
            throw new ServiceException("处理设备上下线通知消息时发生错误: " + e.getMessage(), e);
        }
    }

    /**
     * 处理未知notifyType的消息
     *
     * @param rootNode   JSON格式的消息根节点
     * @param notifyType 未知的notifyType值
     * @throws ServiceException 处理未知消息时发生错误
     */
    private void handleUnknownNotifyTypeMessage(JsonNode rootNode, String notifyType) throws ServiceException {
        try {
            logger.warn("收到未知notifyType的消息: {}, 消息内容: {}", notifyType, rootNode.toString());

            // TODO: 实现未知消息类型的处理逻辑
            // 可以根据需要添加新的消息类型处理
        } catch (Exception e) {
            logger.error("处理未知notifyType消息时发生错误", e);
            throw new ServiceException("处理未知notifyType消息时发生错误: " + e.getMessage(), e);
        }
    }

    /**
     * 解析工作站环境参数数据
     * 支持多种物模型消息格式，包括你提供的格式
     *
     * @param paramsNode 包含环境参数的JSON节点
     * @param envInfo    工作站环境信息对象，用于存储解析后的数据
     * @throws ServiceException 解析参数数据时发生错误
     */
    private void parsePropertyData(JsonNode paramsNode, WorkstationEnv envInfo) throws ServiceException {
        logger.debug("开始解析物模型属性数据，参数节点: {}", paramsNode.toString());

        // 遍历所有参数，动态解析不同类型的属性
        paramsNode.fieldNames().forEachRemaining(fieldName -> {
            try {
                JsonNode propertyNode = paramsNode.get(fieldName);
                if (propertyNode.has("value") && propertyNode.has("time")) {
                    parsePropertyField(fieldName, propertyNode, envInfo);
                }
            } catch (Exception e) {
                logger.warn("解析属性字段 {} 时发生错误: {}", fieldName, e.getMessage());
            }
        });
    }

    /**
     * 解析单个属性字段
     * 基于物模型定义，根据字段名映射到对应的实体属性
     *
     * @param fieldName    属性字段名
     * @param propertyNode 属性节点（包含value和time）
     * @param envInfo      工作站环境信息对象
     */
    private void parsePropertyField(String fieldName, JsonNode propertyNode, WorkstationEnv envInfo) {
        JsonNode valueNode = propertyNode.get("value");
        long timestamp = propertyNode.get("time").asLong();

        // 设置创建时间（使用第一个有效的时间戳）
        if (envInfo.getCreateTime() == null) {
            envInfo.setCreateTime(convertTimestamp(timestamp));
        }

        // 根据物模型定义的属性字段名进行映射
        switch (fieldName) {
            // 温度相关字段 - 物模型定义: CurrentTemperature (float)
            case "CurrentTemperature":
                if (valueNode.isNumber()) {
                    envInfo.setTemperature((float) valueNode.asDouble());
                    logger.debug("解析当前温度数据: {}", valueNode.asDouble());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setTemperature(Float.parseFloat(valueNode.asText()));
                        logger.debug("解析当前温度数据(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析温度数据: {}", valueNode.asText());
                    }
                }
                break;

            // 兼容其他温度字段名
            case "Temperature":
            case "temperature":
                if (valueNode.isNumber()) {
                    envInfo.setTemperature((float) valueNode.asDouble());
                    logger.debug("解析温度数据: {}", valueNode.asDouble());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setTemperature(Float.parseFloat(valueNode.asText()));
                        logger.debug("解析温度数据(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析温度数据: {}", valueNode.asText());
                    }
                }
                break;

            // 湿度相关字段 - 物模型定义: RelativeHumidity (float)
            case "RelativeHumidity":
                if (valueNode.isNumber()) {
                    envInfo.setHumidity((float) valueNode.asDouble());
                    logger.debug("解析相对湿度数据: {}", valueNode.asDouble());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setHumidity(Float.parseFloat(valueNode.asText()));
                        logger.debug("解析相对湿度数据(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析湿度数据: {}", valueNode.asText());
                    }
                }
                break;

            // 兼容其他湿度字段名
            case "Humidity":
                if (valueNode.isNumber()) {
                    envInfo.setHumidity((float) valueNode.asDouble());
                    logger.debug("解析湿度数据: {}", valueNode.asDouble());
                }
                break;

            // 电源状态相关字段 - 物模型定义: PowerStatus (int32)
            case "PowerStatus":
                if (valueNode.isNumber()) {
                    envInfo.setPowerStatus(valueNode.asInt());
                    logger.debug("解析电源状态(数字): {}", valueNode.asInt());
                } else if (valueNode.isTextual()) {
                    String powerValue = valueNode.asText().toLowerCase();
                    envInfo.setPowerStatus("on".equals(powerValue) ? 1 : 0);
                    logger.debug("解析电源状态(字符串): {} -> {}", powerValue, envInfo.getPowerStatus());
                }
                break;

            // 兼容其他电源字段名
            case "Power":
                if (valueNode.isTextual()) {
                    String powerValue = valueNode.asText().toLowerCase();
                    envInfo.setPowerStatus("on".equals(powerValue) ? 1 : 0);
                    logger.debug("解析电源状态: {} -> {}", powerValue, envInfo.getPowerStatus());
                } else if (valueNode.isNumber()) {
                    envInfo.setPowerStatus(valueNode.asInt());
                    logger.debug("解析电源状态: {}", valueNode.asInt());
                }
                break;

            // 烟雾相关字段 - 物模型定义: SmokeScope (float)
            case "SmokeScope":
                if (valueNode.isNumber()) {
                    envInfo.setSmokeScope((float) valueNode.asDouble());
                    logger.debug("解析烟雾传感器数据: {}", valueNode.asDouble());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setSmokeScope(Float.parseFloat(valueNode.asText()));
                        logger.debug("解析烟雾传感器数据(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析烟雾数据: {}", valueNode.asText());
                    }
                }
                break;

            // 兼容其他烟雾字段名
            case "Smoke":
                if (valueNode.isNumber()) {
                    envInfo.setSmokeScope((float) valueNode.asDouble());
                    logger.debug("解析烟雾数据: {}", valueNode.asDouble());
                }
                break;

            // 火焰相关字段 - 物模型定义: FlameScope (float)
            case "FlameScope":
                if (valueNode.isNumber()) {
                    envInfo.setFlameScope((float) valueNode.asDouble());
                    logger.debug("解析火焰传感器数据: {}", valueNode.asDouble());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setFlameScope(Float.parseFloat(valueNode.asText()));
                        logger.debug("解析火焰传感器数据(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析火焰数据: {}", valueNode.asText());
                    }
                }
                break;

            // 兼容其他火焰字段名
            case "Flame":
                if (valueNode.isNumber()) {
                    envInfo.setFlameScope((float) valueNode.asDouble());
                    logger.debug("解析火焰数据: {}", valueNode.asDouble());
                }
                break;

            // 光照强度相关字段 - 物模型定义: LightLuxValue (float)
            case "LightLuxValue":
                if (valueNode.isNumber()) {
                    envInfo.setLightIntensity((float) valueNode.asDouble());
                    logger.debug("解析光照强度值: {}", valueNode.asDouble());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setLightIntensity(Float.parseFloat(valueNode.asText()));
                        logger.debug("解析光照强度值(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析光照强度数据: {}", valueNode.asText());
                    }
                }
                break;

            // 兼容其他光照强度字段名
            case "LightIntensity":
            case "Light":
                if (valueNode.isNumber()) {
                    envInfo.setLightIntensity((float) valueNode.asDouble());
                    logger.debug("解析光照强度: {}", valueNode.asDouble());
                }
                break;

            // 光照状态相关字段 - 物模型定义: LightStatus (int32)
            case "LightStatus":
                if (valueNode.isNumber()) {
                    envInfo.setLightStatus(valueNode.asInt());
                    logger.debug("解析灯光状态: {}", valueNode.asInt());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setLightStatus(Integer.parseInt(valueNode.asText()));
                        logger.debug("解析灯光状态(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析灯光状态数据: {}", valueNode.asText());
                    }
                }
                break;

            // 继电器1状态 - 物模型定义: RelayNum1Status (int32)
            case "RelayNum1Status":
                if (valueNode.isNumber()) {
                    envInfo.setRelayNum1Status(valueNode.asInt());
                    logger.debug("解析继电器1状态: {}", valueNode.asInt());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setRelayNum1Status(Integer.parseInt(valueNode.asText()));
                        logger.debug("解析继电器1状态(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析继电器1状态数据: {}", valueNode.asText());
                    }
                }
                break;

            //
            case "Relay1":
                if (valueNode.isNumber()) {
                    envInfo.setRelayNum1Status(valueNode.asInt());
                    logger.debug("解析继电器1状态: {}", valueNode.asInt());
                }
                break;

            // 继电器2状态 - 物模型定义: RelayNum2Status (int32)
            case "RelayNum2Status":
                if (valueNode.isNumber()) {
                    envInfo.setRelayNum2Status(valueNode.asInt());
                    logger.debug("解析继电器2状态: {}", valueNode.asInt());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setRelayNum2Status(Integer.parseInt(valueNode.asText()));
                        logger.debug("解析继电器2状态(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析继电器2状态数据: {}", valueNode.asText());
                    }
                }
                break;

            // 兼容其他继电器2字段名
            case "Relay2":
                if (valueNode.isNumber()) {
                    envInfo.setRelayNum2Status(valueNode.asInt());
                    logger.debug("解析继电器2状态: {}", valueNode.asInt());
                }
                break;

            // 热敏传感器相关字段 - 物模型定义: HeatScope (float)
            case "HeatScope":
                if (valueNode.isNumber()) {
                    envInfo.setHeatScope((float) valueNode.asDouble());
                    logger.debug("解析热敏传感器数据: {}", valueNode.asDouble());
                } else if (valueNode.isTextual()) {
                    try {
                        envInfo.setHeatScope(Float.parseFloat(valueNode.asText()));
                        logger.debug("解析热敏传感器数据(字符串): {}", valueNode.asText());
                    } catch (NumberFormatException e) {
                        logger.warn("无法解析热敏传感器数据: {}", valueNode.asText());
                    }
                }
                break;

            // 兼容其他热敏字段名
            case "Heat":
                if (valueNode.isNumber()) {
                    envInfo.setHeatScope((float) valueNode.asDouble());
                    logger.debug("解析热敏传感器数据: {}", valueNode.asDouble());
                }
                break;

            // 用户名字段 - 物模型定义: Username (string) 对应UserInfo.username
            case "username":
                if (valueNode.isTextual()) {
                    String username = valueNode.asText();
                    envInfo.setCurUsername(username); // 存储username到curUsername字段
                    logger.debug("解析用户名: {}", username);
                }
                break;

            default:
                logger.debug("未识别的属性字段: {} = {} (类型: {})", fieldName, valueNode.toString(), valueNode.getNodeType());
                break;
        }
    }

    private void handleLabEnvData(String productId, WorkstationEnv envInfo) throws ServiceException {
        if (envInfo.getHumidity() != null && envInfo.getTemperature() != null) {
            Integer labId = labInfoMapper.selectIdByLabCode(productId);
            if (labId != null) {
                LabEnv labEnv = new LabEnv();
                labEnv.setLabId(labId);
                labEnv.setHumidity(envInfo.getHumidity());
                labEnv.setTemperature(envInfo.getTemperature());
                labEnv.setCreateTime(envInfo.getCreateTime());
                labEnv.setSmokeScope(envInfo.getSmokeScope());
                if (labEnvMapper.insert(labEnv) <= 0) {
                    throw new ServiceException("保存实验室环境数据失败");
                }
            }
        }
    }

    /**
     * 将时间戳转换为上海时区的LocalDateTime对象
     *
     * @param timestamp 时间戳，单位为毫秒
     * @return 返回上海时区的LocalDateTime对象
     */
    private LocalDateTime convertTimestamp(long timestamp) {
        // 将时间戳转换为Instant对象
        return Instant.ofEpochMilli(timestamp)
                // 将Instant对象设置为上海时区
                .atZone(ZoneId.of("Asia/Shanghai"))
                // 转换为LocalDateTime对象
                .toLocalDateTime();
    }
}
